<?php
/**
 * 	Created on 06.05.2009
 *	@author Daniel Schmidt
 * 	Die Klasse ACL modelliert alle Funktionen der dieser Seite zugrunde liegenden
 * 	Access-Control-Liste (Zugriffskontrollliste, Rechteverwaltung). Beim initialisieren
 * 	einer Instanz der Klasse ACL wird an Hand der BenutzerID aus der Sessionvariablen
 * 	eine Liste von Berechtigungen erstellt, die beim Aufruf der einzelnen Seiten des
 * 	Internetangebots verifiziert werden können.

 */
  require_once 'toolkit/settings.php';
 require_once  SERVERPATH . '/classes/DB.php';
 
 class ACL {
 	
 	var $mysql;
 	var $perms		= array();
 	var $userID		= 0;
 	var $userRoles	= array();
 	
 	
 	/* Konstruktor
 	 * Anlegen eines neuen Datenbankobjekts und setzten der Instanzvariable: userID 
 	 */
 	function __construct($userID = '') {
 		$this->mysql = new DB();				// Datenbankverbindung aufbauen
 		if($userID != '') {						// Userid nicht mit �bergeben?
 			$this->userID = floatval($userID);	
 		} else {
 			$this->userID = floatval($_SESSION['userID']);	// UserID aus Sessionvariablen holen
 		}
 		$this->userRoles = $this->getUserRoles('ids');			// Nutzerrollen-IDs holen
 		$this->buildACL();										// Rechteliste generieren
 	}
 	
 	/* PHP4 Ersatzkonstruktor
 	 * Falls __construc nicht automatisch aufgerufen wird
 	 */
 	function ACL($userID = '') {
 		$this->__construct($userID);
 	}
 	
 	

	/* Holen der Benutzerrollen des aktuellen Users
	 * R�ckgabe: Array mit f�r den Benutzer angelegten Rollen-ID's
	 */
	function getUserRoles() {
		$query = "SELECT roleID FROM stedano_acl_user_roles WHERE userID = ?";
		$res = array();											// Resultat-Array anlegen
		$roleID = null; 
		if($stmt = $this->mysql->conn->prepare($query)) {		// Statement vorbereiten
			$stmt->bind_param('i', floatval($this->userID));	// Abfrageparameter definieren
			$stmt->execute();									// Abfrage abfeuern
			$stmt->bind_result($roleID);						// Resultate an Schleifenvariable binden
			while($stmt->fetch()) {								// Resultate auswerten
				$res[] = $roleID;								// Resultat als neues Element in das Array �berf�hren
			}
		}
		return $res;											// R�ckgabe des Arrays
	}
	
	
	/* Liste aller aktuell vorhandenen Nutzerrollen holen
	 * 
	 */
	function getAllRoles($format = 'ids') {
		$format = strtolower($format);
		$query 	= "SELECT ID, roleName FROM stedano_acl_roles ORDER BY roleName ASC";
		$res 	= array();
		$roleID = null; $roleName = null;
		
		if($stmt->mysql->conn->prepare($query)) {
			$stmt->execute();
			$stmt->bind_result($roleID, $roleName);
			while($stmt->fetch()) {
				if($format == 'full') {
					$res = array("ID" => $roleID, "Name" => $roleName);
				} else {
					$res = $roleID;
				}
			}
		}
		return $res;
	}
	
	/* Rechtetabelle für den Benutzer aufbauen
	 * Dabei werden Rechte abgeleitet aus der Gruppe, in der sich der User befindet, abgeleitet
	 * und zus�tzlich eventuell gesetzte Spezielberechtigungen hinzugef�gt.
	 */
	function buildACL () {
		if(count($this->userRoles) > 0) {
			$this->perms = array_merge($this->perms, $this->getRolePerms($this->userRoles));
		}
		$this->perms = array_merge($this->perms, $this->getUserPerms($this->userID));
	}
	
	/* Hole den TabellenSchl�ssel der Berechtigung mit der �bergebenen ID
	 * 
	 */	
	function getPermKeyFromID($permID) {
		$query = "SELECT permKey FROM stedano_acl_permissions WHERE ID = ?";
		$permKey = null;
		if($stmt = $this->mysql->conn->prepare($query)) {
			
			$stmt->bind_param('i', floatval($permID));
			$stmt->execute();
			$stmt->bind_result($permKey);
			while($stmt->fetch()) {
				$res = $permKey;
			}
		}
	
		return $res;
	}
	
	/* Hole den Namen der Berechtigung mit der �bergebenen ID
	 * 
	 */
	function getPermNameFromID($permID) {
		$query = "SELECT permName FROM stedano_acl_permissions WHERE ID = ?";
		$permName = null;
		if($stmt = $this->mysql->conn->prepare($query)) {
			$stmt->bind_param('i', floatval(permID));
			$stmt->execute();
			$stmt->bind_result($permName);
			while($stmt->fetch()) {
				$res = $permName;
			}
		}
		return $res;
	}
	
	/* Hole den Namen der Nutzerrolle mit der �bergebenen ID
	 * 
	 */
	function getRoleNameFromID($roleID) {
		$query = "SELECT roleName FROM stedano_acl_roles WHERE ID = ?";
		$roleName = null;
		if($stmt = $this->mysql->conn->prepare($query)) {
			$stmt->bind_param('i', floatval($this->roleID));
			$stmt->execute();
			$stmt->bind_result($roleName);
			while($stmt->fetch()) {
				$res = $roleName;
			}
		}
		return $res;
	}
	
	
	/* Hole den Benutzernamen zu einer �bergebenen ID
	 * 
	 */
	function getUserName($userID) {
		$query = "SELECT username FROM stedano_acl_users WHERE ID = ? LIMIT 1";
		$userName = null;
		if($stmt = $this->mysql->conn->prepare($query)) {
			$stmt->bind_param('i', floatval($this->userID));
			$stmt->execute();
			$stmt->bind_result($userName);
			while($stmt->fetch()) {
				$res = $userName;
			}
		}
		return $res;
	}
	
	/* Hole Rechte, die aus einer Rolle hervorgehen .. 
	 * 
	 */
	function getRolePerms($role) {
		if(is_array($role)) {
			$query = "SELECT permID,value FROM stedano_acl_role_perms WHERE roleID IN (" . implode(",",$role) . ") ORDER BY ID ASC";
		} else {
			$query = "SELECT permID,value FROM stedano_acl_role_perms WHERE roleID = " . floatval($role) . " ORDER BY ID ASC";
		}
		
		$perms = array();
		
		if($stmt = $this->mysql->conn->prepare($query)) {
			$stmt->execute();
			$stmt->bind_result($permID, $value);
			$tmp = array();						// Zwischenspeicher
			$i = 0;
			while($stmt->fetch()) {
				$tmp[] = array("permID" => $permID, "value" => $value);
			}
			foreach($tmp as $v) {
				$pk = strtolower($this->getPermKeyFromID($v['permID']));
				if($pk == '') { continue;}
				if($v['value'] == '1') {
					$hasPermission = true;
				} else {
					$hasPermission = false;
				}
				$perms[$pk] = array('perm' => $pk, 'inheritted' => true, 'value' => $hasPermission, 'Name' => $this->getPermNameFromID($permID), 'ID' => $permID);
				
			}
		}
		return $perms;
			
	} // of getRolePerms
	
	
	/* Hole Rechte, die dem �bergebenen User zugeordnet werden k�nnen 
	 * 
	 */
	function getUserPerms($userID) {
		
		$query = "SELECT ID, userID, permID, value FROM stedano_acl_user_perms WHERE userID = ? ORDER BY addDate ASC";
		$perms = array();
		
		if($stmt = $this->mysql->conn->prepare($query)) {
			$stmt->bind_param('i', floatval($userID));
			$stmt->execute();
			$stmt->bind_result($id, $userID, $permID, $value);
			while($stmt->fetch()) {
				$pk = strtolower($this->getPermKeyFromID($permID));
				if($pk == '') { continue;}
				if($value == '1') {
					$hasPermission = true;
				} else {
					$hasPermission = false;
				}
				$perms[$pk] = array('perm' => $pk, 'inheritted' => false, 'value' => $hasPermission, 'Name' => $this->getPermNameFromID($permID), 'ID' => $permID);
			}
		}
		return $perms;
	}
	
	/* Hole alle Rechte
	 * 
	 */
	 function getAllPerms($format = 'ids') {
	 	$format = strtolower($format);
		$query 	= "SELECT * FROM stedano_acl_permissions ORDER BY permName ASC";
		$res 	= array();
		if($stmt->mysql->conn->prepare($query)) {
			$stmt->execute();
			$stmt->bind_result($ID, $permName, $permName, $permKey);
			while($stmt->fetch()) {
				if($format == 'full') {
					$res[$permKey] = array("ID" => $ID, "Name" => $permName, "Key" => $permKey);
				} else {
					$res = $ID;
				}
			}
		}
		return $res;
	 }
	 
	function deleteRolesAndPermsForUser() {
		// Berechtigungen löschen
		$query = "DELETE FROM stedano_acl_user_perms WHERE userID = ?";
 		if($stmt = $this->mysql->conn->prepare($query)) {		
    			$stmt->bind_param('i', $this->userID);		
    			if(!$stmt->execute()) {
    				new Error("Löschen der Berechtigungen fehlgeschlagen", false);	
    			} 
    		$stmt->close();						
 		}	
 		
 		// Rollen löschen
 		$query = "DELETE FROM stedano_acl_user_roles WHERE userID = ?";
 		if($stmt = $this->mysql->conn->prepare($query)) {		
    			$stmt->bind_param('i', $this->userID);		
    			if(!$stmt->execute()) {
    				new Error("Löschen der Rollen fehlgeschlagen", false);	
    			} 
    		$stmt->close();						
 		}	
	}
	 
	 /* Pr�fe, ob User ROllen hat
	  * 
	  */
	function userHasRole($roleID) {
		foreach($this->userRoles as $k => $v) {
			if(floatval($v) == floatval($roleID)) {
				return true;
			}
		}
		return false;
	}
	
	function hasPermission($permKey) {
		$permKey = strtolower($permKey);
		if(array_key_exists($permKey, $this->perms)) {
			if($this->perms[$permKey]['value'] == '1' || $this->perms[$permKey]['value'] == true) {
				return true;
			} else {
				return false;
			}	
		} else {
			return false;
		}
	}
	
 }
 
?>
